﻿#region zh-CHS 2006 - 2007 DemoSoft 团队 | en 2006 - 2007 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the G.O.S.E(Game Online Server Engine) for .NET.
//
//                 2006-2007 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com
// 
// optimize BaseMap : Thank DanielChen

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using Demo_G.O.S.E.ServerEngine.Util;
using Demo_G.O.S.E.ServerEngine.Item;
using Demo_G.O.S.E.ServerEngine.Common;
using Demo_G.O.S.E.ServerEngine.Network;
using Demo_G.O.S.E.ServerEngine.Creature;
#endregion

// 可移动的物体
// 可视
// 更新血
// 移动
// 攻击
// 给出经验和道具
// 给出是否升级
// 检测是否上面已经更新则发送相应的数据包

// 道具的物体
// 清除已无效的掉落道具
// 可视
// 装备上
// 道具状态改变

// 地图
// 所有的道具
// 所有的人物

// 地图 -> 人物&道具

namespace Demo_G.O.S.E.ServerEngine.Map
{
    // 地图的信息
    //////////////////////////////////////////////////////////////////////////
    // 给出某个坐标点范围内的数据(Mobile/Item/Client)
    // 
    // 
    // 
    // 
    // 
    // 
    // 

    /// <summary>
    /// 
    /// </summary>
    public class BaseMap : IComparable, IComparable<BaseMap>
    {
        #region zh-CHS 类常量 | en Class Constants
        /// <summary>
        /// 空地图
        /// </summary>
        public static readonly BaseMap NullMap = new BaseMap( -1, 0, 0, string.Empty );
        #endregion

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 初始化此地图时的切片数值
        /// </summary>
        private long m_SectorSize = s_SectorSize;
        /// <summary>
        /// 地图宽
        /// </summary>
        private long m_SectorsWidth = 0;
        /// <summary>
        /// 地图高
        /// </summary>
        private long m_SectorsHeight = 0;
        /// <summary>
        /// 地图的全部地图点的数据
        /// </summary>
        private Sector[][] m_Sectors = null;
        #endregion

        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mapID"></param>
        /// <param name="mapIndex"></param>
        /// <param name="fileIndex"></param>
        /// <param name="iWidth"></param>
        /// <param name="iHeight"></param>
        /// <param name="iSeason"></param>
        /// <param name="strName"></param>
        /// <param name="mapRules"></param>
        public BaseMap( Serial iMapID, long iWidth, long iHeight, string strMapName )
        {
            m_MapID = iMapID;
            m_Width = iWidth;
            m_Height = iHeight;
            m_MapName = strMapName;

            m_SectorsWidth = iWidth;
            m_SectorsHeight = iHeight;

            m_SectorSize = s_SectorSize;

            long iSectorsWidth = m_SectorsWidth / m_SectorSize;
            ++iSectorsWidth; // +1 原因(1:小于s_SectorSize(确保保存地图点存在),2:正好整除(InternalGetSector(...)计算时需求),3:有余数)

            long iSectorsHeight = m_SectorsHeight / m_SectorSize;
            ++iSectorsHeight; // +1 原因(1:小于s_SectorSize(确保保存地图点存在),2:正好整除(InternalGetSector(...)计算时需求),3:有余数)

            m_Sectors = new Sector[iSectorsWidth][];
            for ( int iIndex = 0; iIndex < iSectorsWidth; iIndex++ )
            {
                m_Sectors[iIndex] = new Sector[iSectorsHeight];

                for ( int iIndex2 = 0; iIndex2 < iSectorsHeight; iIndex2++ )
                    m_Sectors[iIndex][iIndex2] = new Sector( iIndex, iIndex2, m_SectorSize, this );
            }
        }
        #endregion

        #region zh-CHS 共有属性 | en Public Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private Serial m_MapID;
        #endregion
        /// <summary>
        /// 地图的ID
        /// </summary>
        public Serial MapID
        {
            get { return m_MapID; }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private long m_Width;
        #endregion
        /// <summary>
        /// 地图的宽
        /// </summary>
        public long Width
        {
            get { return m_Width; }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private long m_Height;
        #endregion
        /// <summary>
        /// 地图的高
        /// </summary>
        public long Height
        {
            get { return m_Height; }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 地图名
        /// </summary>
        private string m_MapName;
        #endregion
        /// <summary>
        /// 地图名
        /// </summary>
        public string MapName
        {
            get { return m_MapName; }
        }
        #endregion

        #region zh-CHS 共有静态属性 | en Public Static Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private static long s_MaxVisualRange = 42;
        /// <summary>
        /// 
        /// </summary>
        private static long s_MaxVisualRangeSize = s_MaxVisualRange * 2;
        #endregion
        /// <summary>
        /// 最小的可视化的范围
        /// </summary>
        public static long MaxVisualRange
        {
            get { return s_MaxVisualRange; }
            set
            {
                if ( s_MaxVisualRange > 0 )
                {
                    s_MaxVisualRange = value;
                    s_MaxVisualRangeSize = s_MaxVisualRange * 2;
                }
            }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private static long s_MinVisualRange = 32;
        /// <summary>
        /// 
        /// </summary>
        private static long s_MinVisualRangeSize = s_MinVisualRange * 2;
        #endregion
        /// <summary>
        /// 最大的可视化的范围
        /// </summary>
        public static long MinVisualRange
        {
            get { return s_MinVisualRange; }
            set
            {
                if ( s_MinVisualRange > 0 )
                {
                    s_MinVisualRange = value;
                    s_MinVisualRangeSize = s_MinVisualRange * 2;
                }
            }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private static long s_SectorActiveRange = s_SectorSize;
        #endregion
        /// <summary>
        /// 地图激活时的数值
        /// </summary>
        public static long SectorActiveRange
        {
            get { return s_SectorActiveRange; }
            set
            {
                if ( s_SectorActiveRange > 0 )
                    s_SectorActiveRange = value;
            }
        }


        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 切片地图时的数值
        /// </summary>
        private static long s_SectorSize = 10;
        #endregion
        /// <summary>
        /// 切片地图时的数值
        /// </summary>
        public static long SectorSize
        {
            get { return s_SectorSize; }
            set
            {
                if ( s_SectorSize > 0 )
                    s_SectorSize = value;
            }
        }
        #endregion

        #region zh-CHS 方法 | en Method

        #region zh-CHS 给出坐标获取地图内的某个区域点 | en
        /// <summary>
        /// 给出x,y点的地图该点的数据
        /// </summary>
        /// <param name="point3D"></param>
        /// <returns></returns>
        public Sector GetSector( Point3D point3D )
        {
            return GetSector( point3D.X, point3D.Y );
        }

        /// <summary>
        /// 给出x,y点的地图该点的数据
        /// </summary>
        /// <param name="point2D"></param>
        /// <returns></returns>
        public Sector GetSector( IPoint3D point3D )
        {
            return GetSector( point3D.X, point3D.Y );
        }

        /// <summary>
        /// 给出x,y点的地图该点的数据
        /// </summary>
        /// <param name="point2D"></param>
        /// <returns></returns>
        public Sector GetSector( Point2D point2D )
        {
            return GetSector( point2D.X, point2D.Y );
        }

        /// <summary>
        /// 给出x,y点的地图该点的数据
        /// </summary>
        /// <param name="point2D"></param>
        /// <returns></returns>
        public Sector GetSector( IPoint2D point2D )
        {
            return GetSector( point2D.X, point2D.Y );
        }

        /// <summary>
        /// 给出x,y点的地图该点的数据
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public Sector GetSector( long x, long y )
        {
            if ( x >= 0 && x < m_SectorsWidth && y >= 0 && y < m_SectorsHeight )
                return m_Sectors[x / m_SectorSize][y / m_SectorSize];
            else
                return Sector.NullSector;
        }
        #endregion

        #region zh-CHS 进入或离开地图区域点 | en
        /// <summary>
        /// 改变人物的网络客户端连接
        /// </summary>
        /// <param name="oldState"></param>
        /// <param name="newState"></param>
        /// <param name="m"></param>
        protected internal void OnClientChange( NetState oldState, NetState newState, BaseCreature baseMobile )
        {
            Sector l_Sector = GetSector( baseMobile );
            if ( l_Sector == Sector.NullSector )
                return;
            else
            {
                if ( l_Sector == baseMobile.Sector )
                    l_Sector.OnClientChange( oldState, newState );
            }
        }

        /// <summary>
        /// 人物进入新的地图区域点
        /// </summary>
        /// <param name="m"></param>
        protected internal void OnEnter( BaseCreature baseMobile )
        {
            Sector l_Sector = GetSector( baseMobile );
            if ( l_Sector == Sector.NullSector )
                return;
            else
            {
                if ( l_Sector != baseMobile.Sector )
                {
                    l_Sector.OnEnter( baseMobile );
                    baseMobile.Sector = l_Sector;
                }
            }
        }

        /// <summary>
        /// 道具进入新的地图区域点
        /// </summary>
        /// <param name="item"></param>
        protected internal void OnEnter( BaseItem baseItem )
        {
            Sector l_Sector = GetSector( baseItem );
            if ( l_Sector == Sector.NullSector )
                return;
            else
            {
                if ( l_Sector != baseItem.Sector )
                {
                    l_Sector.OnEnter( baseItem );
                    baseItem.Sector = l_Sector;
                }
            }
        }

        /// <summary>
        /// 人物离开新的地图区域点
        /// </summary>
        /// <param name="m"></param>
        protected internal void OnLeave( BaseCreature baseMobile )
        {
            Sector l_Sector = GetSector( baseMobile );
            if ( l_Sector == Sector.NullSector )
                return;
            else
            {
                if ( l_Sector != baseMobile.Sector )
                {
                    l_Sector.OnLeave( baseMobile );
                    baseMobile.Sector = Sector.NullSector;
                }
            }
        }

        /// <summary>
        /// 道具离开新的地图区域点
        /// </summary>
        /// <param name="item"></param>
        protected internal void OnLeave( BaseItem baseItem )
        {
            Sector l_Sector = GetSector( baseItem );
            if ( l_Sector == Sector.NullSector )
                return;
            else
            {
                if ( l_Sector != baseItem.Sector )
                {
                    l_Sector.OnLeave( baseItem );
                    baseItem.Sector = Sector.NullSector;
                }
            }
        }

        /// <summary>
        /// 人物移动到新的地图区域点, 并离开旧的地图区域点
        /// </summary>
        /// <param name="oldLocation"></param>
        /// <param name="m"></param>
        protected internal void OnMove( Point3D oldLocation, BaseCreature baseMobile )
        {
            Sector l_OldSector = GetSector( oldLocation );
            if ( l_OldSector == Sector.NullSector )
                return;

            Sector l_NewSector = GetSector( baseMobile.Location );
            if ( l_NewSector == Sector.NullSector )
                return;

            if ( l_OldSector != l_NewSector )
            {
                l_OldSector.OnLeave( baseMobile );
                baseMobile.Sector = Sector.NullSector;

                l_NewSector.OnEnter( baseMobile );
                baseMobile.Sector = l_NewSector;
            }
        }

        /// <summary>
        /// 道具移动到旧的地图区域点, 并离开新的地图区域点
        /// </summary>
        /// <param name="oldLocation"></param>
        /// <param name="item"></param>
        protected internal void OnMove( Point3D oldLocation, BaseItem baseItem )
        {
            Sector l_OldSector = GetSector( oldLocation );
            if ( l_OldSector == Sector.NullSector )
                return;

            Sector l_NewSector = GetSector( baseItem.Location );
            if ( l_NewSector == Sector.NullSector )
                return;

            if ( l_OldSector != l_NewSector )
            {
                l_OldSector.OnLeave( baseItem );
                baseItem.Sector = Sector.NullSector;

                l_NewSector.OnEnter( baseItem );
                baseItem.Sector = l_NewSector;
            }
        }
        #endregion

        #region zh-CHS 给出某个坐标点范围内的数据(BaseMobile/BaseItem/NetState)

        #region 给出 Objects(BaseMobile/BaseItem) 的数据
        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <returns></returns>
        public IPooledEnumerable GetObjectsInRange( Point3D point3D )
        {
            return PooledEnumerable.Instantiate( ObjectEnumerator.Instantiate( this, new Rectangle2D( point3D.X - s_MinVisualRange, point3D.Y - s_MinVisualRange, s_MinVisualRangeSize, s_MinVisualRangeSize ) ) );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <param name="iRange"></param>
        /// <returns></returns>
        public IPooledEnumerable GetObjectsInRange( Point3D point3D, int iRange )
        {
            return PooledEnumerable.Instantiate( ObjectEnumerator.Instantiate( this, new Rectangle2D( point3D.X - iRange, point3D.Y - iRange, iRange * 2, iRange * 2 ) ) );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Bounds"></param>
        /// <returns></returns>
        public IPooledEnumerable GetObjectsInBounds( Rectangle2D Bounds )
        {
            return PooledEnumerable.Instantiate( ObjectEnumerator.Instantiate( this, Bounds ) );
        }
        #endregion

        #region 给出 Clients(NetState) 的数据
        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <returns></returns>
        public IPooledEnumerable GetClientsInRange( Point3D point3D )
        {
            return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( point3D.X - s_MinVisualRange, point3D.Y - s_MinVisualRange, s_MinVisualRangeSize, s_MinVisualRangeSize ), SectorType.Clients ) );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <param name="iRange"></param>
        /// <returns></returns>
        public IPooledEnumerable GetClientsInRange( Point3D point3D, int iRange )
        {
            return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( point3D.X - iRange, point3D.Y - iRange, iRange * 2, iRange * 2 ), SectorType.Clients ) );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Bounds"></param>
        /// <returns></returns>
        public IPooledEnumerable GetClientsInBounds( Rectangle2D Bounds )
        {
            return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, Bounds, SectorType.Clients ) );
        }
        #endregion

        #region 给出 BaseItem 的数据
        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <returns></returns>
        public IPooledEnumerable GetItemsInRange( Point3D point3D )
        {
            return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( point3D.X - s_MinVisualRange, point3D.Y - s_MinVisualRange, s_MinVisualRangeSize, s_MinVisualRangeSize ), SectorType.Items ) );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <param name="iRange"></param>
        /// <returns></returns>
        public IPooledEnumerable GetItemsInRange( Point3D point3D, int iRange )
        {
            return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( point3D.X - iRange, point3D.Y - iRange, iRange * 2, iRange * 2 ), SectorType.Items ) );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Bounds"></param>
        /// <returns></returns>
        public IPooledEnumerable GetItemsInBounds( Rectangle2D Bounds )
        {
            return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, Bounds, SectorType.Items ) );
        }
        #endregion

        #region 给出 BaseMobile 的数据
        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <returns></returns>
        public IPooledEnumerable GetMobilesInRange( Point3D point3D )
        {
            return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( point3D.X - s_MinVisualRange, point3D.Y - s_MinVisualRange, s_MinVisualRangeSize, s_MinVisualRangeSize ), SectorType.Mobiles ) );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <param name="iRange"></param>
        /// <returns></returns>
        public IPooledEnumerable GetMobilesInRange( Point3D point3D, int iRange )
        {
            return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( point3D.X - iRange, point3D.Y - iRange, iRange * 2, iRange * 2 ), SectorType.Mobiles ) );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Bounds"></param>
        /// <returns></returns>
        public IPooledEnumerable GetMobilesInBounds( Rectangle2D Bounds )
        {
            return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, Bounds, SectorType.Mobiles ) );
        }
        #endregion

        #endregion

        #region zh-CHS 检测某个坐标点是否可以安置某事物 | en
        /// <summary>
        /// 
        /// </summary>
        /// <param name="point2D"></param>
        /// <param name="z"></param>
        /// <param name="iHeight"></param>
        /// <param name="checkBlocksFit"></param>
        /// <returns></returns>
        public bool CanFit( Point2D point2D, long z )
        {
            return CanFit( point2D.X, point2D.Y, z );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="point2D"></param>
        /// <param name="z"></param>
        /// <param name="iHeight"></param>
        /// <param name="checkBlocksFit"></param>
        /// <returns></returns>
        public bool CanFit( IPoint2D point2D, long z )
        {
            return CanFit( point2D.X, point2D.Y, z );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <param name="iHeight"></param>
        /// <returns></returns>
        public bool CanFit( Point3D point3D )
        {
            return CanFit( point3D.X, point3D.Y, point3D.Z );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <param name="iHeight"></param>
        /// <returns></returns>
        public bool CanFit( IPoint3D point3D )
        {
            return CanFit( point3D.X, point3D.Y, point3D.Z );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <param name="iHeight"></param>
        /// <param name="checkBlocksFit"></param>
        /// <param name="checkMobiles"></param>
        /// <param name="requireSurface"></param>
        /// <returns></returns>
        public bool CanFit( long x, long y, long z )
        {
            if ( x < 0 || y < 0 || x >= m_Width || y >= m_Height )
                return false;

            return true;
        }
        #endregion

        #region zh-CHS 在区域内的某个坐标点是否可刷怪 | en
        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <returns></returns>
        public bool CanSpawnMobile( Point3D point3D )
        {
            return CanSpawnMobile( point3D.X, point3D.Y, point3D.Z );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="point3D"></param>
        /// <returns></returns>
        public bool CanSpawnMobile( IPoint3D point3D )
        {
            return CanSpawnMobile( point3D.X, point3D.Y, point3D.Z );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="point2D"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public bool CanSpawnMobile( Point2D point2D, int z )
        {
            return CanSpawnMobile( point2D.X, point2D.Y, z );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="point2D"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public bool CanSpawnMobile( IPoint2D point2D, int z )
        {
            return CanSpawnMobile( point2D.X, point2D.Y, z );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public bool CanSpawnMobile( long x, long y, long z )
        {
            return CanFit( x, y, z );
        }
        #endregion

        #region zh-CHS 激活/无效地图区域点 | en
        /// <summary>
        /// 激活地图区域点内的BaseItem或BaseMobile,当有新的玩家加入的时候会激活,表示怪物可以攻击了,没有玩家的时候可以不用动了.
        /// </summary>
        /// <param name="cx">范围点x</param>
        /// <param name="cy">范围点y</param>
        internal void ActivateSectors( Sector sector )
        {
            for ( long indexX = sector.X - s_SectorActiveRange; indexX <= sector.X + s_SectorActiveRange; indexX += m_SectorSize )
            {
                for ( long indexY = sector.Y - s_SectorActiveRange; indexY <= sector.Y + s_SectorActiveRange; indexY += m_SectorSize )
                {
                    Sector l_Sector = GetSector( indexX, indexY );
                    if ( l_Sector != Sector.NullSector )
                        l_Sector.Activate();
                }
            }
        }

        /// <summary>
        /// 无效地图区域点内的BaseItem或BaseMobile
        /// </summary>
        /// <param name="cx">范围点x</param>
        /// <param name="cy">范围点y</param>
        internal void DeactivateSectors( Sector sector )
        {
            for ( long indexX = sector.X - s_SectorActiveRange; indexX <= sector.X + s_SectorActiveRange; indexX += m_SectorSize )
            {
                for ( long indexY = sector.Y - s_SectorActiveRange; indexY <= sector.Y + s_SectorActiveRange; indexY += m_SectorSize )
                {
                    Sector l_Sector = GetSector( indexX, indexY );
                    if ( l_Sector != Sector.NullSector && PlayersInRange( l_Sector.X, l_Sector.Y, s_SectorActiveRange ) == false ) // 如果有玩家不存在
                        l_Sector.Deactivate();
                }
            }
        }
        #endregion

        #region zh-CHS 地图区域点是否有玩家存在 | en
        /// <summary>
        /// 检查某个区域内是否有玩家存在
        /// </summary>
        /// <param name="sector"></param>
        /// <param name="iRange"></param>
        /// <returns></returns>
        public bool PlayersInRange( Point2D point2D, long iRange )
        {
            return PlayersInRange( point2D.X, point2D.Y, iRange );
        }

        /// <summary>
        /// 检查某个区域内是否有玩家存在
        /// </summary>
        /// <param name="sector"></param>
        /// <param name="iRange"></param>
        /// <returns></returns>
        public bool PlayersInRange( IPoint2D point2D, long iRange )
        {
            return PlayersInRange( point2D.X, point2D.Y, iRange );
        }

        /// <summary>
        /// 检查某个区域内是否有玩家存在
        /// </summary>
        /// <param name="sector"></param>
        /// <param name="iRange"></param>
        /// <returns></returns>
        public bool PlayersInRange( long x, long y, long iRange )
        {
            for ( long indexX = x - iRange; indexX <= x + iRange; indexX += m_SectorSize )
            {
                for ( long indexY = y - iRange; indexY <= y + iRange; indexY += m_SectorSize )
                {
                    Sector l_CheckSector = GetSector( indexX, indexY );
                    if ( l_CheckSector != Sector.NullSector && l_CheckSector.PlayersCount > 0 )
                        return true;
                }
            }

            return false;
        }
        #endregion

        #region zh-CHS 确保坐标点在地图的边界内 | en
        /// <summary>
        /// 确保x,y在地图的边界内
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="newX"></param>
        /// <param name="newY"></param>
        public void Bound( long x, long y, out long newX, out long newY )
        {
            if ( x < 0 )
                newX = 0;
            else if ( x >= m_Width )
                newX = m_Width - 1;
            else
                newX = x;

            if ( y < 0 )
                newY = 0;
            else if ( y >= m_Height )
                newY = m_Height - 1;
            else
                newY = y;
        }

        /// <summary>
        /// 确保Point2D坐标点在地图的边界内
        /// </summary>
        /// <param name="point2D"></param>
        /// <returns></returns>
        public Point2D Bound( Point2D point2D )
        {
            long x = point2D.X;
            long y = point2D.Y;

            if ( x < 0 )
                x = 0;
            else if ( x >= m_Width )
                x = m_Width - 1;

            if ( y < 0 )
                y = 0;
            else if ( y >= m_Height )
                y = m_Height - 1;

            return new Point2D( x, y );
        }
        #endregion

        #region zh-CHS 杂项 | en
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return m_MapName;
        }
        #endregion

        #endregion

        #region zh-CHS 接口实现 | en Interface Implementation
        /// <summary>
        /// 
        /// </summary>
        /// <param name="otherBaseMap"></param>
        /// <returns></returns>
        public int CompareTo( BaseMap otherBaseMap )
        {
            if ( otherBaseMap == null )
                return 1;

            return m_MapID.CompareTo( otherBaseMap.m_MapID );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="xObject"></param>
        /// <returns></returns>
        public int CompareTo( object xObject )
        {
            return CompareTo( xObject as BaseMap );
        }
        #endregion
    }
}
#endregion

